import { def } from './utils'

// 得到Array.prototype
const arrayPrototype = Array.prototype

// 以Array.prototype为原型创建arrayMethods对象
export const arrayMethods = Object.create(arrayPrototype)

// 要被改写的七个数组方法
const methodsNeedChange = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse']

methodsNeedChange.forEach(methodsName => {
  // 备份原来的方法(因为基本功能还是需要使用原来的数组方法,只是我们需要添加响应式的功能)
  const original = arrayPrototype[methodsName]

  // 定义新的方法
  def(
    arrayMethods,
    methodsName,
    function () {
      // 也要有原来方法的功能
      const result = original.apply(this, arguments)
      let args = Array.from(arguments)

      // 在这个数组中,__ob__已经被添加了,可以将__ob__取出来
      const ob = this.__ob__

      // 由于push,unshift,splice可以往数组中添加项,所以也需要对这些项进行遍历
      let inserted = []
      switch (methodsName) {
        case 'push':
        case 'unshift':
          inserted = arguments
          break
        case 'splice':
          // slice(2)从下标为二的项开始
          // 因为splice格式(下标,数量,插入新的项)
          inserted = args.slice(2)
          // console.log(123, arguments)
          break
      }
      // 判断有没有要插入的新项,如果有就让新项也变为响应式的
      if (inserted) {
        ob.observeArray(inserted)
      }
      // 数组被更改的时候也需要触发notify
      ob.dep.notify()
      return result
    },
    false
  )
})
